//-----------------------------------------------------------------------------
// Name: AnimateObjectManager.cpp
// Auth: Paul Godfrey, Dante Ratto, Rob Darty
// Desc: Keeps a list of AnimateObjects
//-----------------------------------------------------------------------------

#include "AnimateObjectManager.h"
#include "AnimateObject.h"
#include "Systems.h"
#include "DisplayManager.h"
#include <math.h>
#include <iostream>
#include <windows.h>
#include "DeadHuman.h"
#include "DeadCow.h"
#include "CollisionDetect.h"

using namespace std;

cAnimateObjectManager gAnimateObjectManager;

//-----------------------------------------------------------------------------
// Functions:
//-----------------------------------------------------------------------------
cAnimateObjectManager* GetAnimateObjectManager()
{
	return &gAnimateObjectManager;
}

cAnimateObjectManager::cAnimateObjectManager()
{
	mZombies = true;
	mBoss = false;
	mBossSetup= true;
	mBossPoint=1;
}

cAnimateObjectManager::~cAnimateObjectManager()
{
}

//Adds the boss object to the boss list
void cAnimateObjectManager::AddBoss()
{
	cAnimateObject* newAnimateObject = GetAnimateObject();
	newAnimateObject->SetType(kBoss);
	newAnimateObject->SetPosition(1.0f, 0.0f, 1.0f);
	liBossObjects.push_back(*newAnimateObject);
}

//Adds a zombie, spawned from boss, to boss list
void cAnimateObjectManager::AddBossSpawn(float x, float z)
{
	cAnimateObject* newAnimateObject = GetAnimateObject();
	newAnimateObject->SetType(kZombie);
	newAnimateObject->SetPosition(x, 0.0f, z);
	liBossObjects.push_back(*newAnimateObject);
}

//Adds one AnimateObject to the manager - queue position is irrelevent so it always adds to the front.
void cAnimateObjectManager::AddAnimateObject(enum eObjectType eType, float offsetX, float offsetZ, float maxX, float maxZ, int listnum )
{
	cAnimateObject* newAnimateObject = GetAnimateObject();
	newAnimateObject->SetRandomX(maxX, offsetX);
	newAnimateObject->SetRandomZ(maxZ, offsetZ);
	float yaw = (float)((rand()%359)+1);
	newAnimateObject->SetYaw(yaw);
	newAnimateObject->SetPosition(newAnimateObject->GetRandomX(), 0.0f, newAnimateObject->GetRandomZ());
	newAnimateObject->SetType(eType);
	//liAnimateObject.push_back(*newAnimateObject);
	vAnimateLists[listnum].push_back(*newAnimateObject);

}

//Removes 1 AnimateObject from the list if that AnimateObject has reached the end of its life (the mFired bool
//changes to false).
void cAnimateObjectManager::RemoveAnimateObject( float elapsedTimeS, int area )
{
	cDisplayManager* pDisplayManager = GetDisplayManager();

	//If player is not in boss area
	if(!mBoss)
	{

		int numcheck[3];
		if(area!=-1 && area!=24 && area!=23 && area!=-2 && area!=-99 && area!=-100)
		{

		if(area==0)
		{
			numcheck[0]=0;
			numcheck[1]=1;
			numcheck[2]=22;
		}
		else if(area==22)
		{
			numcheck[0]=22;
			numcheck[1]=0;
			numcheck[2]=21;
		}
		else
		{
			numcheck[0]=area;
			numcheck[1]=area+1;
			numcheck[2]=area-1;
		}
		for(int i=0; i<3; i++)
		{
		   list<cAnimateObject>* liAnimateObject=&vAnimateLists[numcheck[i]];

		if(!(liAnimateObject->empty()))
		{	
			list<cAnimateObject>::iterator itAnimateObject = liAnimateObject->begin();
			for(itAnimateObject; itAnimateObject != liAnimateObject->end();)
			{
				cAnimateObject *aoTest = &*itAnimateObject;
				
				int healthTest = aoTest->GetHealth();

				if(healthTest <= 0)
				{
					if(healthTest!=-9199)
					{
						if(itAnimateObject->GetType()==kHuman)
						{
							pDisplayManager->SetPoints(pDisplayManager->GetPoints()-10);
						}
						if(itAnimateObject->GetType()==kZombie || itAnimateObject->GetType()==kCowZombie)
						{
							pDisplayManager->SetPoints(pDisplayManager->GetPoints()+10);
							pDisplayManager->SetDead(2);
						}
						if(itAnimateObject->GetType()==kHumanVaccinated)
						{
							pDisplayManager->SetPoints(pDisplayManager->GetPoints()-20);
							pDisplayManager->SetDead(3);
						
						}
					}
				//	itAnimateObject->~cAnimateObject();
					itAnimateObject = liAnimateObject->erase(itAnimateObject);

				}
				else
				{
					itAnimateObject++;
				}
			}
		}
			}
		}
	}
	//If player IS in boss area
	else
	{
		list<cAnimateObject>* liAnimateObject=&liBossObjects;

		if(!(liAnimateObject->empty()))
		{	
			list<cAnimateObject>::iterator itAnimateObject = liAnimateObject->begin();
			for(itAnimateObject; itAnimateObject != liAnimateObject->end();)
			{
				cAnimateObject *aoTest = &*itAnimateObject;
				
				int healthTest = aoTest->GetHealth();

				if(healthTest <= 0)
				{
					if(healthTest!=-9199)
					{
						if(itAnimateObject->GetType()==kHuman)
						{
							pDisplayManager->SetPoints(pDisplayManager->GetPoints()-10);
						}
						if(itAnimateObject->GetType()==kZombie || itAnimateObject->GetType()==kCowZombie)
						{
							pDisplayManager->SetPoints(pDisplayManager->GetPoints()+10);
							pDisplayManager->SetDead(2);
						}
						if(itAnimateObject->GetType()==kHumanVaccinated)
						{
							pDisplayManager->SetPoints(pDisplayManager->GetPoints()-20);
							pDisplayManager->SetDead(3);
						
						}
					}
					itAnimateObject = liAnimateObject->erase(itAnimateObject);

				}
				else
				{
					itAnimateObject++;
				}
			}
		}
	}
}

//Add an inanimate object of type eType to bucket for area
void cAnimateObjectManager::AddTypeToArea(enum eObjectType eType, int area)
{
	area-=1;
	//Populate Area 1
	if(area==0)
	{
		AddAnimateObject(eType, -35.0f, -135.0f, 50.0f, 15.0f, area);
	}

	////Populate Area 2
	if(area==1)
	{
		AddAnimateObject(eType, -100.0f, -110.0f, 15.0f, 40.0f, area);
	}

	////Populate Area 3
	if(area==2)
	{
		AddAnimateObject(eType, -165.0f, -85.0f, 50.0f, 15.0f, area);
	}

	////Populate Area 4
	if(area==3)
	{
		AddAnimateObject(eType, -197.5f, -35.0f, 17.5f, 35.0f, area);
	}

	////Populate Area 5
	if(area==4)
	{
		AddAnimateObject(eType, -197.5f, 40.0f, 17.5f, 40.0f, area);
	}

	////Populate Area 6
	if(area==5)
	{
		AddAnimateObject(eType, -155.0f, 65.0f, 25.0f, 15.0f, area);
	}

	////Populate Area 7
	if(area==6)
	{
		AddAnimateObject(eType, -145.0f, 105.0f, 15.0f, 25.0f, area);
	}

	////Populate Area 8
	if(area==7)
	{
		AddAnimateObject(eType, -120.0f, 180.0f, 50.0f, 50.0f, area);
	}
	//
	////Populate Area 9
	if(area==8)
	{
		AddAnimateObject(eType, -50.0f, 195.0f, 20.0f, 15.0f, area);
	}

	////Populate Area 10
	if(area==9)
	{
		AddAnimateObject(eType, 5.0f, 195.0f, 35.0f, 15.0f, area);
	}

	////Populate Area 11
	if(area==10)
	{
		AddAnimateObject(eType, 70.0f, 195.0f, 30.0f, 15.0f, area);
	}

	////Populate Area 12
	if(area==11)
	{
		AddAnimateObject(eType, 115.0f, 170.0f, 15.0f, 40.0f, area);
	}

	////Populate Area 13
	if(area==12)
	{
		AddAnimateObject(eType, 150.0f, 145.0f, 20.0f, 15.0f, area);
	}

	////Populate Area 14
	if(area==13)
	{
		AddAnimateObject(eType, 185.0f, 125.0f, 15.0f, 35.0f, area);
	}

	////Populate Area 15
	if(area==14)
	{
		AddAnimateObject(eType, 150.0f, 105.0f, 20.0f, 15.0f, area);
	}

	////Populate Area 16
	if(area==15)
	{
		AddAnimateObject(eType, 145.0f, 70.0f, 15.0f, 20.0f, area);
	}

	////Populate Area 17
	if(area==16)
	{
		AddAnimateObject(eType, 160.0f, 0.0f, 50.0f, 50.0f, area);
	}

	////Populate Area 18
	if(area==17)
	{
		AddAnimateObject(eType, 190.0f, -65.0f, 15.0f, 15.0f, area);
	}

	////Populate Area 19
	if(area==18)
	{
		AddAnimateObject(eType, 190.0f, -125.0f, 15.0f, 45.0f, area);
	}

	////Populate Area 20
	if(area==19)
	{
		AddAnimateObject(eType, 190.0f, -185.0f, 15.0f, 15.0f, area);
	}

	////Populate Area 21
	if(area==20)
	{
		AddAnimateObject(eType, 145.0f, -185.0f, 30.0f, 15.0f, area);
	}

	////Populate Area 22
	if(area==21)
	{
		AddAnimateObject(eType, 130.0f, -145.0f, 15.0f, 25.0f, area);
	}

	////Populate Area 23
	if(area==22)
	{
		AddAnimateObject(eType, 65.0f, -135.0f, 50.0f, 15.0f, area);
	}
}

//Get whether or not zombies still exist
bool cAnimateObjectManager::GetmZombies()
{
	return mZombies;
}

//Get Boss Setup status 
bool cAnimateObjectManager::GetBossSetup()
{
	return mBossSetup;
}

//Set boss setup status
void cAnimateObjectManager::SetBossSetup(bool b)
{
	mBossSetup = b;
}



//Updates all the AnimateObjects locations and draws them
void cAnimateObjectManager::UpdateAnimateObject(float elapsedTimeS, int area)
{
	static float swapTime = 0 ;
	static float listTime = 0;
	swapTime += elapsedTimeS;
	listTime += elapsedTimeS;

	//Checks once ever 10 seconds to see if all Zombies are Gone 
	//If they are - enables entrance to boss
	if(listTime>klistTime && !(swapTime>kswapTime))
	{
		bool z = false; //set inital to false
		int listCount = 0;

		for(int i=0; i < (int)vAnimateLists.size(); i++)
		{
			//cout<<i<<endl;
			list<cAnimateObject> liAnimateObject=GetParticularList(i);
			if(!liAnimateObject.empty())
			{
				list<cAnimateObject>::iterator itAO =liAnimateObject.begin();
				//int listsize = (int)liAnimateObject->size();
				int listcounter=0;
				while(itAO != liAnimateObject.end())
				{
					if ( itAO->GetType() == kZombie || itAO->GetType() == kCowZombie )
					{
						int area = CheckArea(itAO->GetPositionX(), itAO->GetPositionZ());
						if (area==-99)
						{
							itAO->SetHealth(0);
						}
						z = true;
						break;
					}
					itAO++;
				}
			}
			else
			{
				listCount++;
			}
			if(z==true)
			{
				break;
			}
		}
		//cout<<listCount<<endl;
		//cout<< "Z: "<< z <<endl;
		mZombies = z;
		listTime=0;
	}

   

	int numcheck[3];
	//If not in one of these areas
	if(area!=-1 && area!=23 && area!=24 && area!=-2 && area!=-99 && area!=-100)
	{
		//Set areas to check
		if(area==0)
		{
			numcheck[0]=0;
			numcheck[1]=1;
			numcheck[2]=22;
		}
		else if(area==22)
		{
			numcheck[0]=22;
			numcheck[1]=0;
			numcheck[2]=21;
		}
		else
		{
			numcheck[0]=area;
			numcheck[1]=area+1;
			numcheck[2]=area-1;
		}
		
		//Every 30 seconds - swap random objects around between areas, 
		// unless the player is in or next to one of the areas!
		if(swapTime>kswapTime)
		{
			for(int i=0; i<23; i++)
			{
				int iminus;
				int iplus;
				if(i==0)
				{
					iminus=22;
				}
				else
				{
					iminus = i-1;
				}
				if(i==22)
				{
					iplus = 0;
				}
				else
				{
					iplus=i+1;
				}
				bool notnumcheck=true;
				for(int j=0; j<3; j++)
				{
					if(i==numcheck[j] ||iplus==numcheck[j]||iminus==numcheck[j])
					{
						notnumcheck=false;
					}
					
				}
				if(notnumcheck==true)
				{
					list<cAnimateObject>* liAnimateObject=&vAnimateLists[i];
					
					if(!liAnimateObject->empty())
					{
						bool oneUp = true;
						bool oneDown = true;
						for(int j=0; j<3;j++)
						{
							if((i+1)==numcheck[j])
							{
								oneUp=false;
							}
							if((i-1)==numcheck[j])
							{
								oneDown=false;
							}
						}
						list<cAnimateObject>::iterator itAnimateObject = liAnimateObject->begin();
						enum eObjectType eType = itAnimateObject->GetType();
						if(oneUp && oneDown)
						{
							int direction = rand()%2 + 1;

							if(direction==1)
							{
								
								if(i==22)
								{
									AddTypeToArea(eType, 0);
								}
								else
								{
									AddTypeToArea(eType, i+1);
								}
								itAnimateObject = liAnimateObject->erase(itAnimateObject);
							}
							else
							{
								
								if(i==0)
								{
									AddTypeToArea(eType, 22);
								}
								else
								{
									AddTypeToArea(eType, i-1);
								}
								itAnimateObject = liAnimateObject->erase(itAnimateObject);
							}
						}
						if(oneUp && !oneDown)
						{
							if(area==22)
							{
								AddTypeToArea(eType, 0);
							}
							else
							{
								AddTypeToArea(eType, area+1);
							}
							itAnimateObject = liAnimateObject->erase(itAnimateObject);
						}
						if(oneDown && !oneUp)
						{
							
							if(i==0)
							{
								AddTypeToArea(eType, 22);
							}
							else
							{
								AddTypeToArea(eType, i-1);
							}
							itAnimateObject = liAnimateObject->erase(itAnimateObject);
						}
					}

					notnumcheck=0;
				}
			}

			swapTime=0;
		}

		
		for(int i=0; i<3; i++)
		{
			list<cAnimateObject>* liAnimateObject=&vAnimateLists[numcheck[i]];

			if(!liAnimateObject->empty())
			{

				list<cAnimateObject>::iterator itAnimateObject = liAnimateObject->begin();

				while (itAnimateObject != liAnimateObject->end())
				{
					//added this stuff for death animation test...
					if ( itAnimateObject->GetHealth() <= 0 )
					{
						if ( itAnimateObject->GetType() == kHuman || 
							itAnimateObject->GetType() == kZombie ||
							itAnimateObject->GetType() == kHumanVaccinated )
						{
							cDeadHuman* pDeadHuman = GetDeadHuman();

							pDeadHuman->Move( itAnimateObject->GetPositionX(), itAnimateObject->GetPositionZ() );

							pDeadHuman->Draw();
						}

						if ( itAnimateObject->GetType() == kCow ||
							itAnimateObject->GetType() == kCowZombie )
						{		
							cDeadCow* pDeadCow = GetDeadCow();

							pDeadCow->Move( itAnimateObject->GetPositionX(), itAnimateObject->GetPositionZ() );

							pDeadCow->Draw();
						}
					}

					itAnimateObject->Draw(itAnimateObject->GetType());

					itAnimateObject->Update(elapsedTimeS);
			
					int currentArea = (CheckArea(itAnimateObject->GetPositionX(), itAnimateObject->GetPositionZ()))-1;

					if(currentArea!=numcheck[i])
					{	

						if(currentArea==-1)
						{
							vAnimateLists[24].push_back(*itAnimateObject);
						}
						else if(currentArea!=-99 && currentArea!=-100)
						{
							vAnimateLists[currentArea].push_back(*itAnimateObject);
							itAnimateObject->SetHealth(-9199);
						}
					}
					itAnimateObject++;
				}
			}
		}
	}
	//If in safe starting area - only draw objects
	if(area==-2)
	{

		list<cAnimateObject>* liAnimateObject=&vAnimateLists[0];
		if(!liAnimateObject->empty())
		{

		list<cAnimateObject>::iterator itAnimateObject = liAnimateObject->begin();

		while (itAnimateObject != liAnimateObject->end())
		{
			//added this stuff for death animation test...
			if ( itAnimateObject->GetHealth() <= 0 )
			{
				if ( itAnimateObject->GetType() == kHuman || 
						itAnimateObject->GetType() == kZombie ||
						itAnimateObject->GetType() == kHumanVaccinated )
				{
					cDeadHuman* pDeadHuman = GetDeadHuman();

					pDeadHuman->Move( itAnimateObject->GetPositionX(), itAnimateObject->GetPositionZ() );


					pDeadHuman->Draw();
				}

				if ( itAnimateObject->GetType() == kCow ||
						itAnimateObject->GetType() == kCowZombie )
				{
					cDeadCow* pDeadCow = GetDeadCow();

					pDeadCow->Move( itAnimateObject->GetPositionX(), itAnimateObject->GetPositionZ() );

					pDeadCow->Draw();
				}
			}

			itAnimateObject->Draw(itAnimateObject->GetType());

			//itAnimateObject->Update(elapsedTimeS);
			int currentArea = (CheckArea(itAnimateObject->GetPositionX(), itAnimateObject->GetPositionZ()))-1;

			itAnimateObject++;
		}
	}
		
	liAnimateObject=&vAnimateLists[22];
	if(!liAnimateObject->empty())
	{
		list<cAnimateObject>::iterator itAnimateObject = liAnimateObject->begin();

		while (itAnimateObject != liAnimateObject->end())
		{
			//added this stuff for death animation test...
			if ( itAnimateObject->GetHealth() <= 0 )
			{
				if ( itAnimateObject->GetType() == kHuman || 
						itAnimateObject->GetType() == kZombie ||
						itAnimateObject->GetType() == kHumanVaccinated )
				{
					cDeadHuman* pDeadHuman = GetDeadHuman();

					pDeadHuman->Move( itAnimateObject->GetPositionX(), itAnimateObject->GetPositionZ() );


					pDeadHuman->Draw();
				}

				if ( itAnimateObject->GetType() == kCow ||
						itAnimateObject->GetType() == kCowZombie )
				{
					cDeadCow* pDeadCow = GetDeadCow();

					pDeadCow->Move( itAnimateObject->GetPositionX(), itAnimateObject->GetPositionZ() );

					pDeadCow->Draw();
				}
			}

			itAnimateObject->Draw(itAnimateObject->GetType());
			
			//itAnimateObject->Update(elapsedTimeS);
			int currentArea = (CheckArea(itAnimateObject->GetPositionX(), itAnimateObject->GetPositionZ()))-1;

			itAnimateObject++;
		}
	}
	}
		 
}

//Calculates closest Objects and whether or not to run or go after them
//Only works when Boss area is true
void cAnimateObjectManager::BossAnimateAI(float elapsedTimeS)
{
	cDisplayManager* pDisplayManager = GetDisplayManager();
	list<cAnimateObject>::iterator itAnimateObject;
	
	if(!liBossObjects.empty())
	{
		itAnimateObject = liBossObjects.begin();
		tVector3f ThisPos;
		float distance;
		float currentNearDistance=20000.0f;
		tVector3f Direction;
		Direction[0] = 0.0f;
		Direction[1] = 0.0f;
		Direction[2] = 0.0f;
		while (itAnimateObject != liBossObjects.end())
		{
			if(itAnimateObject->GetType()!=kBoss)
			{
				ThisPos[0]=itAnimateObject->GetPositionX();
				ThisPos[1]=itAnimateObject->GetPositionY();
				ThisPos[2]=itAnimateObject->GetPositionZ();
		
				distance = sqrt((((pDisplayManager->GetCameraX()-ThisPos[0])*(pDisplayManager->GetCameraX()-ThisPos[0]))+((pDisplayManager->GetCameraZ()-ThisPos[2])*(pDisplayManager->GetCameraZ()-ThisPos[2]))));
    			if(distance<currentNearDistance && distance<50.0f)
				{
					Direction[0] = pDisplayManager->GetCameraX()-ThisPos[0];
					Direction[1] = pDisplayManager->GetCameraY()-ThisPos[1];
					Direction[2] = pDisplayManager->GetCameraZ()-ThisPos[2];
				}
				itAnimateObject->SetDirection(Direction);
			}
			else
			{
				float bossX = itAnimateObject->GetPositionX();
				float bossZ = itAnimateObject->GetPositionZ();
				if(mBossPoint==1 && !(bossX > kBossPoint1[0]))
				{
					Direction[0] = kBossPoint1[0]-bossX;
					Direction[1] = 0.0f;
					Direction[2] = kBossPoint1[2]-bossZ;
				}
				else if(mBossPoint==1 && bossX > kBossPoint1[0])
				{
					mBossPoint=2;
				}
				else if(mBossPoint==2 && !(bossZ < kBossPoint2[2]))
				{
					Direction[0] = kBossPoint2[0]-bossX;
					Direction[1] = 0.0f;
					Direction[2] = kBossPoint2[2]-bossZ;
				}
				else if(mBossPoint==2 && bossZ < kBossPoint2[2])
				{
					mBossPoint=3;
				}
				if(mBossPoint==3 && !(bossX < kBossPoint3[0]))
				{
					Direction[0] = kBossPoint3[0]-bossX;
					Direction[1] = 0.0f;
					Direction[2] = kBossPoint3[2]-bossZ;
				}
				else if(mBossPoint==3 && bossX < kBossPoint3[0])
				{
					mBossPoint=4;
				}
				else if(mBossPoint==4 && !(bossZ > kBossPoint4[2]))
				{
					Direction[0] = kBossPoint4[0]-bossX;
					Direction[1] = 0.0f;
					Direction[2] = kBossPoint4[2]-bossZ;
				}
				else if(mBossPoint==4 && bossZ > kBossPoint4[2])
				{
					mBossPoint=1;
				}
				itAnimateObject->SetDirection(Direction);
			}

			itAnimateObject++;
		}
	}

}

//Depricated method to kill everything
void cAnimateObjectManager::UpdateHealth()
{
	for(int i=0; i< (int)vAnimateLists.size(); i++)
	{
		list<cAnimateObject>* liAnimateObjects=&vAnimateLists[i];
		list<cAnimateObject>::iterator itAnimateObject;
		if(!liAnimateObjects->empty())
		{
			itAnimateObject = liAnimateObjects->begin();
			if(itAnimateObject != liAnimateObjects->end())
			{
				itAnimateObject->SetHealth(0);
				itAnimateObject++;
			}
		}
	}
}

//Checks if victory has been achieved or not
bool cAnimateObjectManager::CheckVictory()
{
	bool victory=false;
	list<cAnimateObject>::iterator itAnimateObject = liBossObjects.begin();

	while (itAnimateObject != liBossObjects.end())
	{
		if(itAnimateObject->GetVictoryStatus()==true)
		{
			victory=true;
		}
		itAnimateObject++;
	}
	return victory;
}

//Updates the positions of and draws all objects in boss list
void cAnimateObjectManager::UpdateAnimateBossObjects(float elapsedTimeS)
{

		static float spawnTimer=0;
		spawnTimer+=elapsedTimeS;

	   if(!liBossObjects.empty())
	   {

		list<cAnimateObject>::iterator itAnimateObject = liBossObjects.begin();

		while (itAnimateObject != liBossObjects.end())
		{
			//added this stuff for death animation test...
			if ( itAnimateObject->GetHealth() <= 0 )
			{
				if ( itAnimateObject->GetType() == kHuman || 
						itAnimateObject->GetType() == kZombie ||
						itAnimateObject->GetType() == kHumanVaccinated )
				{
					cDeadHuman* pDeadHuman = GetDeadHuman();

					pDeadHuman->Move( itAnimateObject->GetPositionX(), itAnimateObject->GetPositionZ() );


					pDeadHuman->Draw();
				}

				if ( itAnimateObject->GetType() == kCow ||
						itAnimateObject->GetType() == kCowZombie )
				{
					cDeadCow* pDeadCow = GetDeadCow();

					pDeadCow->Move( itAnimateObject->GetPositionX(), itAnimateObject->GetPositionZ() );

					pDeadCow->Draw();
				}
			}

			itAnimateObject->Draw(itAnimateObject->GetType());

			itAnimateObject->Update(elapsedTimeS);

			//Spawn a sprog
			if(spawnTimer>kSpawnTimer && itAnimateObject->GetType()==kBoss)
			{
				if(liBossObjects.size()<11)
				{
					float bossX = itAnimateObject->GetPositionX();
					float bossZ = itAnimateObject->GetPositionZ();
					if(mBossPoint==1)
					{

						float vectorX = kBossPoint4[0]-bossX;
						float vectorZ = kBossPoint4[2]-bossZ;
						float dist = sqrt((vectorX*vectorX)+(vectorZ*vectorZ));
						if(dist>3.25f)
						{
							float percentage = 3.25f/dist;
							float xPos = bossX+(vectorX*percentage);
							float zPos = bossZ+(vectorZ*percentage);
							AddBossSpawn(xPos, zPos);
						}
					}
					if(mBossPoint==2)
					{
						float vectorX = kBossPoint1[0]-bossX;
						float vectorZ = kBossPoint1[2]-bossZ;
						float dist = sqrt((vectorX*vectorX)+(vectorZ*vectorZ));
						if(dist>3.25f)
						{
							float percentage = 3.25f/dist;
							float xPos = bossX+(vectorX*percentage);
							float zPos = bossZ+(vectorZ*percentage);
							AddBossSpawn(xPos, zPos);
						}
					}
					if(mBossPoint==3)
					{
						float vectorX = kBossPoint2[0]-bossX;
						float vectorZ = kBossPoint2[2]-bossZ;
						float dist = sqrt((vectorX*vectorX)+(vectorZ*vectorZ));
						if(dist>3.25f)
						{
							float percentage = 3.25f/dist;
							float xPos = bossX+(vectorX*percentage);
							float zPos = bossZ+(vectorZ*percentage);
							AddBossSpawn(xPos, zPos);
						}
					}
					if(mBossPoint==4)
					{
						float vectorX = kBossPoint3[0]-bossX;
						float vectorZ = kBossPoint3[2]-bossZ;
						float dist = sqrt((vectorX*vectorX)+(vectorZ*vectorZ));
						if(dist>3.25f)
						{
							float percentage = 3.25f/dist;
							float xPos = bossX+(vectorX*percentage);
							float zPos = bossZ+(vectorZ*percentage);
							AddBossSpawn(xPos, zPos);
						}
					}
				}
				spawnTimer=0.0f;
			}
						
			itAnimateObject++;
		}
	}
}

//Sets boss status
void cAnimateObjectManager::SetBoss(bool b)
{
	mBoss = b;
}

//Gets Boss status
bool cAnimateObjectManager::GetBoss()
{
	return mBoss;
}

//Calculates where or not to run from or go towards an
//attacker or target in the objects area and 
//areas around it. Only works for areas around the player,
//others are ignored
void cAnimateObjectManager::AnimateAI(int area)
{
	cDisplayManager* pDisplayManager = GetDisplayManager();
	int numcheck[3];

	if(area!=-1 && area!= 23 && area !=24  && area!=-2 && area!=-99 && area!=-100)
	{
		if(area==0)
		{
			numcheck[0]=0;
			numcheck[1]=1;
			numcheck[2]=22;
		}
		else if(area==22)
		{
			numcheck[0]=22;
			numcheck[1]=0;
			numcheck[2]=21;
		}
		else
		{
			numcheck[0]=area;
			numcheck[1]=area+1;
			numcheck[2]=area-1;
		}
		
		
		for(int i=0; i<3; i++)
		{

		list<cAnimateObject>* liAnimateObjects=&vAnimateLists[numcheck[i]];
		list<cAnimateObject>::iterator itAnimateObject;
		list<cAnimateObject>::iterator itAnimateTest;

		
		if(!liAnimateObjects->empty())
		{
		itAnimateObject = liAnimateObjects->begin();
		tVector3f ThisPos;
		tVector3f TestPos;
		float distance;
		float currentNearDistance=20000.0f;
		tVector3f Direction;
		Direction[0] = 0.0f;
		Direction[1] = 0.0f;
		Direction[2] = 0.0f;
		while (itAnimateObject != liAnimateObjects->end())
		{
			if(itAnimateObject->GetType()==kZombie || itAnimateObject->GetType()==kCowZombie)
			{
				ThisPos[0]=itAnimateObject->GetPositionX();
				ThisPos[1]=itAnimateObject->GetPositionY();
				ThisPos[2]=itAnimateObject->GetPositionZ();
				for(int j=0; j<3; j++)
				{

					list<cAnimateObject>* liAnimateObjects2=&vAnimateLists[numcheck[j]];
					list<cAnimateObject>::iterator itAnimateObject;
					list<cAnimateObject>::iterator itAnimateTest;
					itAnimateTest = liAnimateObjects2->begin();
					while(itAnimateTest!=liAnimateObjects2->end())
					{
						if(itAnimateTest->GetType()==kHuman || itAnimateTest->GetType()==kCow)
						{
							TestPos[0]=itAnimateTest->GetPositionX();
							TestPos[1]=itAnimateTest->GetPositionY();
							TestPos[2]=itAnimateTest->GetPositionZ();
							distance = sqrt(((TestPos[0]-ThisPos[0])*(TestPos[0]-ThisPos[0]))+((TestPos[2]-ThisPos[2])*(TestPos[2]-ThisPos[2])));
							if (distance<currentNearDistance && distance<50.0f)
							{
								Direction[0] = TestPos[0]-ThisPos[0];
								Direction[1] = TestPos[1]-ThisPos[1];
								Direction[2] = TestPos[2]-ThisPos[2];
								currentNearDistance=distance;
							}
						}
						
						itAnimateTest++;
					}
				}
				distance = sqrt((((pDisplayManager->GetCameraX()-ThisPos[0])*(pDisplayManager->GetCameraX()-ThisPos[0]))+((pDisplayManager->GetCameraZ()-ThisPos[2])*(pDisplayManager->GetCameraZ()-ThisPos[2]))));
    			if(distance<currentNearDistance && distance<50.0f)
				{
					Direction[0] = pDisplayManager->GetCameraX()-ThisPos[0];
					Direction[1] = pDisplayManager->GetCameraY()-ThisPos[1];
					Direction[2] = pDisplayManager->GetCameraZ()-ThisPos[2];
				}
				itAnimateObject->SetDirection(Direction);
			}
			else if(itAnimateObject->GetType()==kHuman || itAnimateObject->GetType()==kCow)
			{
				ThisPos[0]=itAnimateObject->GetPositionX();
				ThisPos[1]=itAnimateObject->GetPositionY();
				ThisPos[2]=itAnimateObject->GetPositionZ();

				for(int j=0; j<3; j++)
				{

					list<cAnimateObject>* liAnimateObjects2=&vAnimateLists[numcheck[j]];
					list<cAnimateObject>::iterator itAnimateObject;
					list<cAnimateObject>::iterator itAnimateTest;
					itAnimateTest = liAnimateObjects2->begin();
					while(itAnimateTest!=liAnimateObjects2->end())
					{
						if(itAnimateTest->GetType()==kZombie || itAnimateTest->GetType()==kCowZombie)
						{
							TestPos[0]=itAnimateTest->GetPositionX();
							TestPos[1]=itAnimateTest->GetPositionY();
							TestPos[2]=itAnimateTest->GetPositionZ();
							distance = sqrt(((TestPos[0]-ThisPos[0])*(TestPos[0]-ThisPos[0]))+((TestPos[2]-ThisPos[2])*(TestPos[2]-ThisPos[2])));
							if (distance<20.0f)
							{
								Direction[0] = ThisPos[0]-TestPos[0];
								Direction[1] = ThisPos[1]-TestPos[1];
								Direction[2] = ThisPos[2]-TestPos[2];
							}
						}
					
						itAnimateTest++;
					}
				}
				itAnimateObject->SetDirection(Direction);

			}

			itAnimateObject++;
		}
	}
	}
		}
}

//Gets vector of lists
vector<list<cAnimateObject>>* cAnimateObjectManager::GetAnimateVector()
{
	return &vAnimateLists;
}

//Gets particular list from vector (unused and crap)
list<cAnimateObject> cAnimateObjectManager::GetParticularList(int i)
{
	return vAnimateLists[i];
}

//gets boss list
list<cAnimateObject>* cAnimateObjectManager::GetBossList()
{
	return &liBossObjects;
}

//Creates lists and adds to vector
void cAnimateObjectManager::CreateVector()
{
	list<cAnimateObject> liAnimateObject01;
	list<cAnimateObject> liAnimateObject02;
	list<cAnimateObject> liAnimateObject03;
	list<cAnimateObject> liAnimateObject04;
	list<cAnimateObject> liAnimateObject05;
	list<cAnimateObject> liAnimateObject06;
	list<cAnimateObject> liAnimateObject07;
	list<cAnimateObject> liAnimateObject08;
	list<cAnimateObject> liAnimateObject09;
	list<cAnimateObject> liAnimateObject10;
	list<cAnimateObject> liAnimateObject11;
	list<cAnimateObject> liAnimateObject12;
	list<cAnimateObject> liAnimateObject13;
	list<cAnimateObject> liAnimateObject14;
	list<cAnimateObject> liAnimateObject15;
	list<cAnimateObject> liAnimateObject16;
	list<cAnimateObject> liAnimateObject17;
	list<cAnimateObject> liAnimateObject18;
	list<cAnimateObject> liAnimateObject19;
	list<cAnimateObject> liAnimateObject20;
	list<cAnimateObject> liAnimateObject21;
	list<cAnimateObject> liAnimateObject22;
	list<cAnimateObject> liAnimateObject23;
	list<cAnimateObject> liAnimateObject24;
	list<cAnimateObject> liAnimateObject25;

	vAnimateLists.push_back(liAnimateObject01);
	vAnimateLists.push_back(liAnimateObject02);
	vAnimateLists.push_back(liAnimateObject03);
	vAnimateLists.push_back(liAnimateObject04);
	vAnimateLists.push_back(liAnimateObject05);
	vAnimateLists.push_back(liAnimateObject06);
	vAnimateLists.push_back(liAnimateObject07);
	vAnimateLists.push_back(liAnimateObject08);
	vAnimateLists.push_back(liAnimateObject09);
	vAnimateLists.push_back(liAnimateObject10);
	vAnimateLists.push_back(liAnimateObject11);
	vAnimateLists.push_back(liAnimateObject12);
	vAnimateLists.push_back(liAnimateObject13);
	vAnimateLists.push_back(liAnimateObject14);
	vAnimateLists.push_back(liAnimateObject15);
	vAnimateLists.push_back(liAnimateObject16);
	vAnimateLists.push_back(liAnimateObject17);
	vAnimateLists.push_back(liAnimateObject18);
	vAnimateLists.push_back(liAnimateObject19);
	vAnimateLists.push_back(liAnimateObject20);
	vAnimateLists.push_back(liAnimateObject21);
	vAnimateLists.push_back(liAnimateObject22);
	vAnimateLists.push_back(liAnimateObject23);
	vAnimateLists.push_back(liAnimateObject24);
	vAnimateLists.push_back(liAnimateObject25);
}